#include <iostream>
#include <string>
#include <functional>
#include <websocketpp/server.hpp>
#include <websocketpp/config/asio_no_tls.hpp>
//服务端对象类型
typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

//事件触发后，回调的函数
//处理http请求的
void http_callback(wsserver_t* srv,websocketpp::connection_hdl hdl)
{
    //后台打印 + 返回一个简单的页面

    //获取当前链接
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);

    //打印信息
    std::cout << conn->get_request_body() << std::endl;
    websocketpp::http::parser::request req = conn->get_request();
    std::cout << req.get_method() << std::endl;
    std::cout << req.get_body() << std::endl;
    std::cout << req.get_uri() << std::endl;

    //响应(一个简单的html网页)
    std::string resBody = "<html><body><h1>Hello word</h1></body></html>";
    conn->set_body(resBody);
    conn->append_header("Contten-Type","text/html");
    conn->set_status(websocketpp::http::status_code::ok);
}

//链接断开
void close_handler(wsserver_t* srv,websocketpp::connection_hdl hdl)
{
    std::cout<<"websock链接断开\n";
}

//连接成功
void open_handler(wsserver_t* srv,websocketpp::connection_hdl hdl)
{
    std::cout<<"websock握手成功\n";
}

//接收到客户端消息
void message_handler(wsserver_t* srv,websocketpp::connection_hdl hdl,wsserver_t::message_ptr msg)
{
    wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);
    std::cout <<"wsmag"<<msg->get_payload()<<std::endl;
    std::string rsp = "client say:" + msg->get_payload();

    conn->send(rsp);
}

int main()
{
    //1、实例化server对象,异步io
    wsserver_t wssrv;
    
    //2、设置日志等级(不打印)
    wssrv.set_access_channels(websocketpp::log::alevel::none);

    //3、初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);//地址重用
    //4、设置回调函数(重点)
    wssrv.set_http_handler(std::bind(http_callback,&wssrv,std::placeholders::_1));
    wssrv.set_close_handler(std::bind(close_handler,&wssrv,std::placeholders::_1));
    wssrv.set_open_handler(std::bind(open_handler,&wssrv,std::placeholders::_1));
    wssrv.set_message_handler(std::bind(message_handler,&wssrv,std::placeholders::_1,std::placeholders::_2));
    //5、设置监听端口
    wssrv.listen(8080);
    //6、开始获取新链接
    wssrv.start_accept();

    //7、启动服务器
    wssrv.run();


    return 0;
}